package com.york.tinyrpc.protoss.fault.retry;

import com.github.rholder.retry.*;
import com.york.tinyrpc.protoss.model.TinyRpcResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 固定时间间隔重试
 * 每次重试时间间隔固定
 */
public class FixedIntervalRetryStrategy implements RetryStrategy {

    private static final Logger log = LoggerFactory.getLogger(FixedIntervalRetryStrategy.class);


    /**
     * 固定时间间隔重试
     *
     * @param target
     * @return TinyRpcResponse
     * @throws ExecutionException
     * @throws RetryException
     */
    public TinyRpcResponse doRetry(Callable<TinyRpcResponse> target) throws ExecutionException, RetryException {
        Retryer<TinyRpcResponse> retryer = RetryerBuilder.<TinyRpcResponse>newBuilder()
                // 遇到异常时触发重试
                .retryIfExceptionOfType(Exception.class)
                // 重试等待策略为固定时间间隔 3秒
                .withWaitStrategy(WaitStrategies.fixedWait(3L, TimeUnit.SECONDS))
                // 停止重试策略-最大重试次数 3次
                .withStopStrategy(StopStrategies.stopAfterAttempt(3))
                // 监听重试次数
                .withRetryListener(new RetryListener() {
                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        long currentTime = attempt.getAttemptNumber();
                        if (currentTime > 1L) {
                            log.info("重试请求次数: {}", attempt.getAttemptNumber() - 1);
                        }
                    }
                })
                .build();
        return retryer.call(target);
    }
}
